package com.fuchuang.seckillsystem.service.impl;

import com.fuchuang.seckillsystem.dto.ActivityQuery;
import com.fuchuang.seckillsystem.dto.KeyConstants;
import com.fuchuang.seckillsystem.dto.PageQuery;
import com.fuchuang.seckillsystem.entity.Activity;
import com.fuchuang.seckillsystem.entity.Goods;
import com.fuchuang.seckillsystem.exception.GlobalException;
import com.fuchuang.seckillsystem.mapper.ActivityMapper;
import com.fuchuang.seckillsystem.mapper.GoodsMapper;
import com.fuchuang.seckillsystem.service.IActivityService;
import com.fuchuang.seckillsystem.service.IGoodService;
import com.fuchuang.seckillsystem.service.ISeckillService;
import com.fuchuang.seckillsystem.vo.RespBeanEnum;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
public class ActivityServiceImpl implements IActivityService {
    
    @Resource
    ActivityMapper activityMapper;
    
    @Resource
    GoodsMapper goodsMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private ISeckillService seckillService;
    
    @Autowired
    private IGoodService goodService;
    
    @Override
    @Transactional
    public void insertActivity(Activity activity) {
        try {
            if (activity.getStartTime().after(activity.getEndTime())) {
                throw new GlobalException(RespBeanEnum.PARAMS_ERROR);
            }
            Date date = new Date();
            activity.setCreateTime(date);
            activity.setUpdateTime(date);
            activity.setIsValid(1);
            activityMapper.insertSelective(activity);
        } catch (Exception e) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_INSERT_ERROR);
        }
    }
    
    private Activity getActivityById(Integer activityId) {
        Boolean hasKey = redisTemplate.hasKey(KeyConstants.SECKILL_ACTIVITY + activityId);
        Activity activity = null;
        if (hasKey != null && hasKey) {
            activity = (Activity) redisTemplate.boundHashOps(KeyConstants.SECKILL_ACTIVITY + activityId).get(KeyConstants.ACTIVITY + activityId);
        } else {
            activity = activityMapper.selectByPrimaryKey(activityId);
            if (Objects.isNull(activity)) {
                throw new GlobalException(RespBeanEnum.ACTIVITY_NOT_EXIST_ERROR);
            }
        }
        return activity;
    }
    
    
    @Override
    @Transactional
    public void deleteActivity(Integer id) {
        Date date = new Date();
        Activity activity = getActivityById(id);
        if (Objects.isNull(activity)) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_NOT_EXIST_ERROR);
        }
        //判断秒杀活动是否允许删除
        if (activity.getStartTime().before(new Date()) && activity.getEndTime().after(new Date())) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_IS_SECKILL);
        }
        activity.setUpdateTime(date);
        activity.setIsValid(0);
        try {
            activityMapper.updateByPrimaryKeySelective(activity);
        } catch (Exception e) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_DELETE_ERROR);
        }
        //删除对应的ms_activity_goods
        List<Goods> goodsList = selectGoodsByActivityId(id);
        List<Integer> goodIds = new ArrayList<>();
        for (Goods goods : goodsList) {
            goodIds.add(goods.getId());
        }
        if (redisTemplate.hasKey(KeyConstants.SECKILL_ACTIVITY + id)) {
            //删除原来redis和缓存中旧的数据
            redisTemplate.delete(KeyConstants.SECKILL_ACTIVITY + id);
        }
        //删除数据库中活动与商品之间的关系
        if (goodIds.size() != 0) {
            deleteActivityGoods(id, goodIds);
        }
    }
    
    @Override
    @Transactional
    public void updateActivity(Activity activity) {
        try {
            if (!Objects.isNull(activity.getEndTime()) && !Objects.isNull(activity.getStartTime())) {
                if (activity.getStartTime().after(activity.getEndTime())) {
                    throw new GlobalException(RespBeanEnum.PARAMS_ERROR);
                }
            }
            //判断秒杀活动是否运行修改
            //判断秒杀活动是否允许删除
            if (activity.getStartTime().before(new Date()) && activity.getEndTime().after(new Date())) {
                throw new GlobalException(RespBeanEnum.ACTIVITY_IS_SECKILL);
            }
            Date date = new Date();
            activity.setUpdateTime(date);
            activityMapper.updateByPrimaryKeySelective(activity);
//            if (redisTemplate.hasKey(KeyConstants.SECKILL_ACTIVITY + activity.getId())) {
//                //删除原来redis和缓存中旧的数据
//                redisTemplate.boundHashOps(KeyConstants.SECKILL_ACTIVITY + activity.getId()).delete(KeyConstants.ACTIVITY + activity.getId());
//                activity = activityMapper.selectByPrimaryKey(activity.getId());
//                redisTemplate.boundHashOps(KeyConstants.SECKILL_ACTIVITY + activity.getId()).put(KeyConstants.ACTIVITY + activity.getId(), activity);
//            }
            seckillService.insertGoodsToRedis(false);
        } catch (Exception e) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_UPDATE_ERROR);
        }
    }
    
    @Override
    public Map<String, Object> selectAllActivity(PageQuery pageQuery) {
        Map<String, Object> map = new HashMap<>();
        PageHelper.startPage(pageQuery.getPage(), pageQuery.getLimit());
        PageInfo<Activity> pageInfo = new PageInfo<>(activityMapper.selectAllActivity());
        map.put("list", pageInfo.getList());
        map.put("count", pageInfo.getTotal());
        return map;
    }
    
    
    @Override
    public Activity selectActivityById(Integer id) {
        return getActivityById(id);
    }
    
    @Override
    public Map<String, Object> selectActivityByDate(ActivityQuery activityQuery) {
        Map<String, Object> map = new HashMap<>();
        PageHelper.startPage(activityQuery.getPage(), activityQuery.getLimit());
        List<Activity> activityList = activityMapper.selectActivityByDate(activityQuery.getPastTime(), activityQuery.getFutureTime());
//        List<Activity> beforeActivity = new ArrayList<Activity>();
//        List<Activity> nowActivity = new ArrayList<Activity>();
//        List<Activity> afterActivity = new ArrayList<Activity>();
//        System.out.println(activityList);
//        for (Activity activity : activityList) {
//            if (activity.getStartTime().after(new Date(System.currentTimeMillis()))) {
//                beforeActivity.add(activity);
//                System.out.println(beforeActivity);
//            } else if (activity.getStartTime().before(new Date(System.currentTimeMillis()))) {
//                nowActivity.add(activity);
//            } else {
//                afterActivity.add(activity);
//            }
//        }
        PageInfo<Activity> pageInfo = new PageInfo<>(activityList);
        map.put("list", pageInfo.getList());
        map.put("count", pageInfo.getTotal());
        return map;
    }
    
    @Override
    public List<Goods> selectGoodsByActivityId(Integer activityId) {
        Activity activity = getActivityById(activityId);
        return goodsMapper.queryGoodsByActivityId(activity.getId());
    }
    
    @Override
    @Transactional
    public void insertActivityGoods(Integer activityId, List<Integer> goodsIds) {
        Activity activity = getActivityById(activityId);
        //判断秒杀活动是否运行修改
        if (activity.getEndTime().before(new Date())) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_HAS_EXPIRED);
        }
        //如果正在秒杀
        if (activity.getStartTime().before(new Date(System.currentTimeMillis() - 10 * 60 * 1000)) && activity.getEndTime().after(new Date())) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_IS_SECKILL);
        }
        for (Integer id : goodsIds) {
            //判断商品是否存在
            goodService.selectGoodsById(id);
            List<Goods> goodsList = goodsMapper.queryGoodsByActivityId(activityId);
            for (Goods good : goodsList) {
                if (good.getId().equals(id)) {
                    throw new GlobalException(RespBeanEnum.ACTIVITY_GOODS_ADD_REPEAT_ERROR);
                }
            }
            List<Activity> activityList = selectActivityByGoodsId(id);
            //判断该商品是否在其他秒杀活动中
            if (activityList.size() != 0) {
                for (Activity act : activityList) {
                    //判断其秒杀活动是否结束，又或者该秒杀活动在需要修改得秒杀活动之前就结束了
                    if (act.getEndTime().after(new Date()) && act.getEndTime().after(activity.getStartTime())) {
                        throw new GlobalException(RespBeanEnum.GOODS_IN_OTHER_ACTIVITIES);
                    }
                }
            }
        }
        activityMapper.insertActivityGoods(activityId, goodsIds);
        seckillService.insertGoodsToRedis(false);
    }
    
    @Override
    @Transactional
    public void deleteActivityGoods(Integer activityId, List<Integer> goodsIds) {
        Activity activity = getActivityById(activityId);
        //判断秒杀活动是否运行修改
        if (activity.getStartTime().before(new Date(System.currentTimeMillis() - 10 * 60 * 1000)) && activity.getEndTime().after(new Date())) {
            throw new GlobalException(RespBeanEnum.ACTIVITY_IS_SECKILL);
        }
        //删除内存标准中得数据
        seckillService.removeGoodsFromIsEmpty(goodsIds, activityId);
        activityMapper.deleteActivityGoods(activityId, goodsIds);
    }
    
    @Override
    public List<Activity> selectActivityByGoodsId(Integer goodsId) {
        return activityMapper.selectActivityByGoodsId(goodsId);
    }
    
}
